<?php

declare(strict_types=1);
/**
 * @copyright 深圳市易果网络科技有限公司
 * @version 1.0.0
 * @link https://dayiguo.com
 */

namespace App\Service\Business;

use App\Dao\BusinessDao;
use App\Dao\CouponCategoryDao;
use App\Dao\CouponDao;
use App\Dao\CouponStockDao;
use App\Job\IntegralJob;
use App\Job\WriteBusinessMoneyJob;
use App\Kernel\Util\UserJwtInstance;
use App\Service\Service;
use App\Dao\UserCouponDao;
use App\Dao\UserDao;
use App\Middleware\Business\BusinessMiddleware;

use App\Service\User\IntegralDetailService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Middleware;

/**
 * 优惠券服务
 *
 * @Middleware(BusinessMiddleware::class)
 * @author 李想(928674263@qq.com)
 * @package App\Service\Business
 */
class CouponService extends Service
{
    /**
     * 注入商家服务
     *
     * @Inject
     * @var BusinessService 
     */
    public $business_service;

    /**
     * 注入商家DAO
     *
     * @Inject
     * @var BusinessDao
     */
    public $business_dao;

    /**
     * 注入优惠券DAO
     *
     * @Inject
     * @var CouponDao
     */
    public $dao;

    /**
     * 注入优惠券分类DAO
     *
     * @Inject
     * @var CouponCategoryDao
     */
    public $category_dao;

    /**
     * 注入优惠券库存DAO
     *
     * @Inject
     * @var CouponStockDao
     */
    public $stock_dao;

    /**
     * 注入优惠券使用DAO
     *
     * @Inject
     * @var UserCouponDao
     */
    public $user_coupon_dao;

    /**
     * 注入用户DAO
     *
     * @Inject
     * @var UserDao
     */
    public $user_dao;

    /**
     * @Inject
     * @var IntegralDetailService
     */
    public $integral_detail_service;

    /**
     * 添加优惠券
     *
     * @param array $data
     */
    public function addCoupon(array $data)
    {
        $user = UserJwtInstance::instance()->build()->getUser();
        $business = $user->business;

//        // 优惠券开始时间 取时间戳
        $data['start_time']  = strtotime($data['start_time']);

//        // 固定截止日期 取时间戳
        $data['expire_time'] = strtotime($data['expire_time']);

        $save_data = [
            'business_id' => $business->id,
            'category_id' => 0,
            'type' => $this->dao::COUPON,
            'title' => $data['title'],
            'description' => $data['description'],
            'price' => $data['price'],
            'goods_price' => $data['goods_price'],
            'picture' => $data['picture'] ?? null,
            'start_time' => $data['start_time'],
            'expire_time' => $data['expire_time'],
            'status' => 0,
            'stock' => $data['stock'],
            'instructions' => $data['instructions'],
        ];

        $result = isset($data['id']) ? $this->dao->update([
            'id' => $data['id']
        ], $save_data) : $this->dao->create($save_data);

        !$result && $this->error();

    }


    /**
     * 获取商家的优惠券列表
     *
     * @return array
     */
    public function getBusinessCouponList()
    {
        $user = UserJwtInstance::instance()->build()->getUser();
        $business = $user->business;

        //判断商家的入驻类型
        if ($business->enable_full_discount > 0) { //全店打折
            $type = $this->dao::SHOP_DISCOUNT;
        } else if ($business->enable_coupon > 0) {
            $type = $this->dao::COUPON;//优惠券
        } else if($business->enable_voucher > 0){//现金抵用券
            $type = $this->dao::ENABLE_VOUCHER;
        } else {
            $type = 0;
        }

        // 获取商家优惠券列表
        $business_coupon_list = $this->dao->getList($type,['business_id' => $business->id, 'type' => $type], 'id desc');

        $result = [];
        foreach ($business_coupon_list as $key => $value) {
            $result[$key] = [
                'id' => $value->id,
                'type' => $value->type,
                'title' => $value->title,
                'price' => $value->price,
                'goods_price' => $value->goods_price,
                'description' => $value->description,
                'start_time' => $value->start_time,
                'expire_time' => $value->expire_time,
                'instructions' => $value->instructions ?? '',
                'sales' => $value->sales,
                'stock' => $value->stock,
                'picture' => $value->picture,
            ];

        }

        return $result;
    }

    /**
     * 删除优惠券
     *
     * @param array $ids
     */
    public function deleteCoupon(array $ids)
    {
        $user = UserJwtInstance::instance()->build()->getUser();
        $business = $user->business;

        $result = $this->dao->update([
            'business_id' => $business->id,
            'id' => ['in', $ids],
        ],['deleted_at' => time()]);

        if (!$result) $this->error();
    }

    /**
     * 添加优惠券库存
     *
     * @param array $data
     * @return array
     * @throws
     */
    public function addCouponStock(array $data)
    {
        $user = UserJwtInstance::instance()->build()->getUser();
        $business = $user->business;

        // 判断优惠券是否存在
        $coupon = $this->dao->find([
            ['id' => $data['coupon_id']],
            ['status' => 1],
        ], ['*'], null, 'COUPON.NOT_FOUND');

        // 判断优惠券是否所属登陆商家
        if ($coupon->business_id !== $business->id) {
            $this->error();
        }

        // 查出所有券核销码
        $all_stock_list = $this->stock_dao->multiple([], ['value']);

        $all_stock_value_list = [];
        foreach ($all_stock_list as $stock) {
            $all_stock_value_list[] = $stock['value'];
        }

        // 券添加时间
        $create_time = time();

        // 过滤掉的核销码 要批量添加的数据
        $filter_arr = $save_data = [];

        foreach ($data['value'] as $key => $code) {
            // 过滤重复核销码
            if (in_array($code, $all_stock_value_list)) {
                $filter_arr[] = $code;

                unset($data['value'][$key]);
            }
            else {
                $save_data[] = [
                    'business_id' => $business->id,
                    'coupon_id' => $data['coupon_id'],
                    'value' => $code,
                    'created_at' => $create_time,
                    'updated_at' => $create_time,
                ];
            }
        }

        $result = $this->stock_dao->makeModel()->insert($save_data);

        !$result && $this->error();

        return $filter_arr;
    }

    /**
     * 通过核销码获取优惠券
     *
     * @param array $data
     * @return mixed
     */
    public function getCouponByStockValue(array $data)
    {
        $user = UserJwtInstance::instance()->build()->getUser();
        $business = $user->business;

        // 判断核销码是否存在
        $coupon_stock = $this->stock_dao->find([
            ['value' => $data['value']],
            ['business_id' => $business->id],
        ], ['*'], null, 'COUPON.STOCK_NOT_FOUND');

        $coupon = $coupon_stock->coupon;

        // 判断优惠券是否存在
        !$coupon && $this->error('COUPON.NOT_FOUND');

        // 判断优惠券状态是否正常
        $coupon->status !== 1 && $this->error('COUPON.STATUS_EXCEPTION');

        // 判断优惠券是否被购买
        if (empty($coupon_stock->user_id) || empty($coupon_stock->buy_time)) {
            $this->error('COUPON.STOCK_EXCEPTION');
        }

        // 判断该核销码是否已经使用过
        if (!empty($coupon_stock->use_time)) {
            $this->error('COUPON.STOCK_VALUE_USED');
        }

        // 判断是否过期
        if (empty($coupon_stock->expire_time) || $coupon_stock->expire_time < time()) {
            $this->error('COUPON.STOCK_EXPIRED');
        }

        $result = [
            'id' => $coupon->id,
            'type' => $coupon->type,
            'title' => $coupon->title,
            'price' => $coupon->price,
            'goods_price' => $coupon->goods_price,
            'description' => $coupon->description,
            'expire_time' => $coupon->expire_time,
            'expire_type' => $coupon->expire_type,
            'sales' => $coupon->sales,
        ];

        // 查询的类型为1要返回的数据
        if ($coupon->type === 1) {
            $result['picture'] = $coupon->picture;
            $result['rebate'] = $coupon->rate;
        }

        // 查询的类型为2要返回的数据
        if ($coupon->type === 2) {
            $result['reach_price'] = $coupon->reach_price;
        }

        return $result;
    }

    /**
     * 核销优惠券
     *
     * @param array $data
     */
    public function   checkCoupon(array $data)
    {
        $user = UserJwtInstance::instance()->build()->getUser();
        $business = $user->business;

        // 判断核销码是否存在
        $coupon_stock = $this->stock_dao->find([
            ['value' => $data['value']],
            ['coupon_id' => $data['coupon_id']],
            ['business_id' => $business->id],
        ], ['*'], null, 'COUPON.STOCK_NOT_FOUND');

        $coupon = $coupon_stock->coupon;

        // 判断优惠券是否存在
        !$coupon && $this->error('COUPON.NOT_FOUND');

        // 判断优惠券状态是否正常
        $coupon->status !== 1 && $this->error('COUPON.STATUS_EXCEPTION');

        // 判断优惠券是否被购买
        if (empty($coupon_stock->user_id) || empty($coupon_stock->buy_time)) {
            $this->error('COUPON.STOCK_EXCEPTION');
        }

        // 判断该核销码是否已经使用过
        if (!empty($coupon_stock->use_time)) {
            $this->error('COUPON.STOCK_VALUE_USED');
        }

        // 判断是否过期
        if (empty($coupon_stock->expire_time) || $coupon_stock->expire_time < time()) {
            $this->error('COUPON.STOCK_EXPIRED');
        }

        // 添加使用时间
        $coupon_stock->use_time = time();
        if (!$coupon_stock->save()) $this->error();
    }

    /**
     * 添加全店打折信息
     * @param array $data
     */
    public function addShopDiscount(array $data)
    {
        $user = UserJwtInstance::instance()->build()->getUser();

        $business = $user->business;

        !$business && $this->error('BUSINESS.NOT_EXIST');

        $save_data = [
            'business_id' => $business->id,
            'category_id' => 0,//暂时默认为0
            'type' => $this->dao::SHOP_DISCOUNT,//全店打折
            'title' => $data['title'],
            'picture' => $data['picture'],
            'status' => 0,
            //全店打折没有的，传个空或者0
            'description' => '',//描述
        ];

        $result = isset($data['id']) ? $this->dao->update([
            'id' => $data['id']
        ], $save_data) : $this->dao->create($save_data);

        !$result && $this->error();

    }

    /**
     * 获取全店打折信息
     *
     * @return array
     */
    public function getShopDiscount() {
        $user = UserJwtInstance::instance()->build()->getUser();
        $business = $user->business;

       if( $business->enable_full_discount > 0 ) { //全店打折
           $type = $this->dao::SHOP_DISCOUNT;
       } else if ( $business-> enable_coupon > 0 ) { //优惠券
           $type = $this->dao::COUPON;
       } else if ( $business->enable_voucher > 0 ) { //现金抵扣券
           $type = $this->dao::ENABLE_VOUCHER;
       } else {
           $type = 0;
       }

        $shop_discount_list = $this->dao->getShopDiscountList(['business_id' => $business->id, 'type' => $type], 'id desc');

        $result = [];
        foreach ($shop_discount_list as $key => $value) {
            $result[$key] = [
                'id' => $value->id,
                'type' => $value->type,
                'title' => $value->title,
                'picture' => $value->picture,
            ];
        }

        return $result;
    }


    /**
     * 添加现金抵用券信息
     * @param array $data
     */
    public function addVoucher(array $data)
    {
        $user = UserJwtInstance::instance()->build()->getUser();

        $business = $user->business;

        !$business && $this->error('BUSINESS.NOT_EXIST');

        $save_data = [
            'business_id' => $business->id,
            'category_id' => 0,//暂时默认为0
            'type' => $this->dao::ENABLE_VOUCHER,//现金抵用券
            'title' => $data['title'],
            'goods_price' => $data['goods_price'],
            'reach_price' => $data['reach_price'],
            'price' => $data['price'],
            'stock' => $data['stock'],
            'status' => 0,
            'start_time' => strtotime($data['start_time']),
            'expire_time' => strtotime($data['expire_time']),
            'instructions' => $data['instructions'],
        ];

        $result = isset($data['id']) ? $this->dao->update([
            ['id' => $data['id']]
        ], $save_data) : $this->dao->create($save_data);

        !$result && $this->error();

    }

    /**
     * 获取现金抵用券信息
     *
     * @return array
     */
    public function getEnableVoucherList()
    {
        $user = UserJwtInstance::instance()->build()->getUser();
        $business = $user->business;

        //判断商家的入驻类型
        if ($business->enable_full_discount > 0) { //全店打折
            $type = $this->dao::SHOP_DISCOUNT;
        } else if ($business->enable_coupon > 0) {
            $type = $this->dao::COUPON;//优惠券
        } else if($business->enable_voucher > 0){//现金抵用券
            $type = $this->dao::ENABLE_VOUCHER;
        } else {
            $type = 0;
        }

        // 获取商家优惠券列表
        $business_coupon_list = $this->dao->getList($type,['business_id' => $business->id, 'type' => $type], 'id desc');

        $result = [];
        foreach ($business_coupon_list as $key => $value) {
            $result[$key] = [
                'id' => $value->id,
                'type' => $value->type,
                'title' => $value->title,
                'price' => $value->price,
                'goods_price' => $value->goods_price,
                'start_time' => $value->start_time,
                'expire_time' => $value->expire_time,
                'instructions' => $value->instructions ?? '',
                'sales' => $value->sales,
                'stock' => $value->stock,
                'reach_price' => $value->reach_price ?? 0,
            ];

        }

        return $result;
    }

    /**
     * 根据id获取具体的信息
     *
     * @param array $data
     * @return mixed
     */
    public function getCouponById( array $data)
    {
        $condition = [
          'id' => $data['id'],
        ];

        $result = $this->dao->getCouponByMap($condition);

        //根据不同的类型，返回不一样的结果
        if ($result['type'] == 1) { //优惠券
            $return_data['id'] = $result['id'];
            $return_data['type'] = $result['type'];
            $return_data['title'] = $result['title'];
            $return_data['description'] = $result['description'];
            $return_data['price'] = $result['price'];
            $return_data['goods_price'] = $result['goods_price'];
            $return_data['start_time'] = $result['start_time'];
            $return_data['expire_time'] = $result['expire_time'];
            $return_data['stock'] = $result['stock'];
            $return_data['picture'] = $result['picture'];
            $return_data['instructions'] = $result['instructions'];
        } else if ($result['type'] == 2) { //现金抵用券
            $return_data['id'] = $result['id'];
            $return_data['type'] = $result['type'];
            $return_data['title'] = $result['title'];
            $return_data['goods_price'] = $result['goods_price'];
            $return_data['reach_price'] = $result['reach_price'];
            $return_data['price'] = $result['price'];
            $return_data['stock'] = $result['stock'];
            $return_data['start_time'] = $result['start_time'];
            $return_data['expire_time'] = $result['expire_time'];
            $return_data['instructions'] = $result['instructions'];
        } else if ($result['type'] == 3) {//全店打折
            $return_data['id'] = $result['id'];
            $return_data['type'] = $result['type'];
            $return_data['title'] = $result['title'];
            $return_data['picture'] = $result['picture'];
        } else {
            $return_data = [];
        }

        !$result && $this->error();

        return $return_data;
    }

    /**
     * 根据类型查询券的列表
     *
     * @param array $data
     * @return mixed
     */
    public function getCouponByType(array $params)
    {
        $business_id = UserJwtInstance::instance()->build()->getUser()->business->id;

        if( empty($business_id) ) {
            $this->error();
        }

        $map = [
            'type' => $params['type'],
            'business_id' => $business_id,
        ];
        $sort = 'updated_at desc';

        $result_list = $this->dao->getCouponListByType( $map, $sort);

        $result = [];
        foreach ($result_list as $key => $value) {
            switch ($params['type']) {
                case "1":
                    $result[$key] = [
                        'id' => $value->id,
                        'type' => $value->type,
                        'status' => $value->status,
                        'title' => $value->title,
                        'price' => $value->price,
                        'goods_price' => $value->goods_price,
                        'start_time' => $value->start_time,
                        'expire_time' => $value->expire_time,
                        'instructions' => $value->instructions ?? '',
                        'sales' => $value->sales,
                        'stock' => $value->stock,
                        'reach_price' => $value->reach_price ?? 0,
                        'description' => $value->description ?? '',
                        'describe' => $value->description ?? '',
                    ];
                    break;
                case "2":
                    $result[$key] = [
                        'id' => $value->id,
                        'type' => $value->type,
                        'status' => $value->status,
                        'title' => $value->title,
                        'price' => $value->price,
                        'goods_price' => $value->goods_price,
                        'reach_price' => $value->reach_price ?? 0,
                        'stock' => $value->stock,
                        'start_time' => $value->start_time,
                        'expire_time' => $value->expire_time,
                        'instructions' => $value->instructions ?? '',
                        'sales' => $value->sales,
                        'description' => $value->description ?? '',
                        'describe' => $value->description ?? '',
                    ];
                    break;
                case "3":
                    $result[$key] = [
                        'id' => $value->id,
                        'type' => $value->type,
                        'status' => $value->status,
                        'title' => $value->title,
                        'picture' => $value->picture,
                        'sales' => $value->sales,
                        'describe' => $value->sales,
                    ];
                    break;
                default:
                    $result = [];
            }
        }

        !$result_list && $this->error();

        return $result;
    }

    /**
     * 查询商家的核销后的券的信息
     *
     * @return mixed
     * @param int $status
     */
    public function getUsedCoupon(int $status)
    {
        $user = UserJwtInstance::instance()->build()->getUser();
        $business = $user->business;

        $statusList = [
            // 已使用
            1 => ['use_time' => ['>', 0], 'status' => $this->user_coupon_dao::STATUS_RECEIVED],
            // 可用优惠券
            2 => ['status' => $this->user_coupon_dao::STATUS_PAID,'use_time' => 0, 'expire_time' => ['>', time()]],
            // 已过期
            3 => ['use_time' => 0, 'expire_time' => ['<', time()]]
        ];
        $map = $statusList[$status] ?? [];

        $map['business_id'] = $business->id;

        $sort = 'updated_at desc';

        //查询出该店家的使用过的券
        $result_list = $this->user_coupon_dao->getUserCouponList( $map , $sort );

        return $result_list;
    }

    /**
     * 通过订单编号更改优惠券订单状态信息
     *
     * @param array $data
     * @return mixed
     */
    public function changeUserCouponStatus(array $data)
    {
        $user = UserJwtInstance::instance()->build()->getUser();
        $business = $user->business;

        $user_coupon_info = $this->user_coupon_dao->first(['order_no'=>$data['order_no']]);

        if( $business->id !=  $user_coupon_info['business_id']) {
            $this->error('COUPON.NOT_BUSINESS_COUPON');
        }

        //判断订单是否完成
        if ( $user_coupon_info['status'] == $this->user_coupon_dao::STATUS_RECEIVED ) {
            $this->error('COUPON.STOCK_VALUE_USED');
        }

        $condition = [
            'order_no' => $data['order_no'],
            'status' => $this->user_coupon_dao::STATUS_PAID,
        ];

        $update_data = [
            'status' => $this->user_coupon_dao::STATUS_RECEIVED,
            'use_time' => time(),
        ];

        $result = $this->user_coupon_dao->update([$condition],$update_data);

        //返回更新状态后优惠券订单详情
        if ( $result ) {
            $updated_detail = $this->user_coupon_dao->getUserCouponFirst([
                'order_no' => $data['order_no'],
                'status' => $this->user_coupon_dao::STATUS_RECEIVED,
            ],'id desc');
            $business = $this->business_dao->first(['id'=>$updated_detail->business_id],['name','logo']);
            $this->integral_detail_service->integral_detail_dao->create([
                'user_id' => $updated_detail->user_id,
                'status' => $this->integral_detail_service->integral_detail_dao::CONSUME_INTEGRAL,
                'type' => $this->integral_detail_service->integral_detail_dao::INCOME_TYPE,
                'num' => $updated_detail->total_price,
                'remark' => '消费送积分',
                'order_no' => $updated_detail->order_no,
                'goods_name' => $business['name'],
                'goods_pic' => $business['logo'],
                'amount' => $updated_detail->price,
            ]);

            $this->driver->push(new IntegralJob( $updated_detail->user_id ));

            $this->driver->push(new WriteBusinessMoneyJob( $data['order_no'] ));
        }

        !$result && $this->error();

        return $updated_detail;
    }
}